package co.yixiang.yshop.module.member.api.user;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import co.yixiang.yshop.framework.common.enums.CommonStatusEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.module.member.api.user.dto.MemberUserRespDTO;
import co.yixiang.yshop.module.member.api.user.dto.UserAddressDto;
import co.yixiang.yshop.module.member.api.user.dto.UserBillDto;
import co.yixiang.yshop.module.member.api.user.dto.WechatUserDto;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.dal.dataobject.useraddress.UserAddressDO;
import co.yixiang.yshop.module.member.dal.dataobject.userbill.UserBillDO;
import co.yixiang.yshop.module.member.dal.mysql.user.MemberUserMapper;
import co.yixiang.yshop.module.member.dal.mysql.userbill.UserBillMapper;
import co.yixiang.yshop.module.member.enums.BillDetailEnum;
import co.yixiang.yshop.module.member.enums.BillEnum;
import co.yixiang.yshop.module.member.service.user.MemberUserService;
import co.yixiang.yshop.module.member.service.useraddress.AppUserAddressService;
import co.yixiang.yshop.module.member.service.userbill.UserBillService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;

/**
 * 会员用户的 API 实现类
 *
 * @author yshop
 */
@Service
@Validated
public class MemberUserApiImpl implements MemberUserApi {
    @Resource
    private MemberUserMapper memberUserMapper;
    @Resource
    private UserBillMapper userBillMapper;

    @Resource
    private MemberUserService userService;

    @Resource
    private UserBillService userBillService;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private AppUserAddressService appUserAddressService;

    @Override
    public UserAddressDto getUserAddress(Long id) {
        UserAddressDO userAddress = appUserAddressService.getById(id);
        return UserConvert.INSTANCE.convert(userAddress);
    }

    @Override
    public void saveWechatMember(WechatUserDto wechatUserDto) {
        MemberUserDO user = new MemberUserDO();
        user.setNickname(wechatUserDto.getNickname());
        user.setAvatar(wechatUserDto.getHeadimgurl());
        // 生成密码
        String password = IdUtil.fastSimpleUUID();
        user.setPassword(encodePassword(password));
        user.setUsername(wechatUserDto.getOpenid());
        user.setLoginType("wechat");
        user.setWxProfile(wechatUserDto);

        userService.save(user);
    }

    @Override
    public MemberUserRespDTO getUser(Long id) {
        MemberUserDO user = userService.getUser(id);
        return UserConvert.INSTANCE.convert2(user);
    }

    @Override
    public List<MemberUserRespDTO> getUsers(Collection<Long> ids) {
        return UserConvert.INSTANCE.convertList2(userService.getUserList(ids));
    }

    @Override
    public List<MemberUserRespDTO> getUserListByNickname(String nickname) {
        return UserConvert.INSTANCE.convertList2(userService.getUserListByNickname(nickname));
    }

    @Override
    public MemberUserRespDTO getUserByMobile(String mobile) {
        return UserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile));
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void decPrice(Long uid, BigDecimal payPrice) {
        memberUserMapper.decPrice(payPrice,uid);
    }

    @Override
    public String getUserBill(String orderId) {
        UserBillDO userBillDO =  userBillService.getOne(new LambdaQueryWrapper<UserBillDO>().eq(UserBillDO::getExtendField,orderId));
        if(userBillDO != null) {
            userBillDO.setStatus(ShopCommonEnum.IS_STATUS_1.getValue());
            userBillService.updateById(userBillDO);
            userService.incMoney(userBillDO.getUid(), userBillDO.getNumber());
            return "1";
        }
        return "0";
    }

    @Override
    public void incPayCount(Long uid) {
        userService.incPayCount(uid);
    }

    @Override
    public int expend(Long uid, String title, String category, String type, double number, double balance, String mark) {
        UserBillDO userBill = UserBillDO.builder()
                .uid(uid)
                .title(title)
                .category(category)
                .type(type)
                .number(BigDecimal.valueOf(number))
                .balance(BigDecimal.valueOf(balance))
                .mark(mark)
                .pm(BillEnum.PM_0.getValue())
                .build();

       return userBillMapper.insert(userBill);
    }

    @Override
    public void addIntegral(Long uid, BigDecimal addIntegral,String orderId) {
        MemberUserDO user = userService.getUser(uid);
        BigDecimal newIntegral = NumberUtil.add(addIntegral, user.getIntegral());
        user.setIntegral(newIntegral);
        userService.updateById(user);

        //增加流水
        userBillService.income(uid, "积分回退", BillDetailEnum.CATEGORY_2.getValue(),
                BillDetailEnum.TYPE_8.getValue(),
                addIntegral.doubleValue(),
                newIntegral.doubleValue(),
                "购买商品失败,回退积分" + addIntegral, orderId);
    }

    /**
     * 对密码进行加密
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        return passwordEncoder.encode(password);
    }

}
